package jaux.tank.generator.component;

import java.awt.Component;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JPanel;

import jaux.tank.generator.domain.TankApplication;
import jaux.tank.generator.domain.TankApplication.ApplicationType;
import jaux.tank.generator.domain.TankApplication.AuthenticationType;
import jaux.tank.generator.domain.TankApplication.BuildTool;
import jaux.tank.generator.domain.TankApplication.CacheProvider;
import jaux.tank.generator.domain.TankApplication.ClientFramework;
import jaux.tank.generator.domain.TankApplication.DatabaseType;
import jaux.tank.generator.domain.TankApplication.DevDatabaseType;
import jaux.tank.generator.domain.TankApplication.ProdDatabaseType;
import jaux.tank.generator.domain.TankApplication.SearchEngine;
import jaux.tank.generator.domain.TankApplication.ServiceDiscoveryType;
import jaux.tank.generator.domain.TankApplication.Websocket;
import jaux.tank.generator.jd.components.JdCheckBox;
import jaux.tank.generator.jd.components.JdComboBox;
import jaux.tank.generator.jd.components.JdLabeledInput;
import jaux.tank.generator.jd.components.JdTextField;
import jaux.tank.generator.jd.layout.JdGridLayout;
import lombok.Getter;
import lombok.Setter;

public class ApplicationEditorPanel extends JPanel{

	private static final long serialVersionUID = 1L;

	@Getter
	private TankApplication  application;
	
	@Getter
	@Setter
	private boolean saved;
	
	public ApplicationEditorPanel(TankApplication app) {
		this.application = app;
		initializeComponents();
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
	private void initializeComponents() {
        setLayout(new JdGridLayout(0, 2));
        
        List<JdLabeledInput<?, ?>> clientFields = new ArrayList<>();
        List<JdLabeledInput<?, ?>> serverFields = new ArrayList<>();
        
        // name field
        JdTextField nameTextField = new JdTextField("Name:",application.getName());
//        nameTextField.setEditable(false);
        nameTextField.onChange(t -> application.setName(t));
		add(nameTextField);
		 // input field for port
        JdTextField serverPortTextField = new JdTextField("Server Port:", ""+application.getServerPort());
        serverPortTextField.onChange(t -> application.setServerPort(Integer.parseInt(t)));
        add(serverPortTextField);
        
		JdComboBox<ApplicationType> applicationTypeComboBox = new JdComboBox<>("Application Type:",application.getApplicationType(),ApplicationType.values());
		applicationTypeComboBox.setEditable(false);
		applicationTypeComboBox.onChange(value->application.setApplicationType(value));
		add(applicationTypeComboBox);
        
        JdComboBox<AuthenticationType> authTypeComboBox = new JdComboBox<>("Authentication Type:",application.getAuthenticationType(), AuthenticationType.values());
        authTypeComboBox.onChange(value->application.setAuthenticationType(value));
        add(authTypeComboBox);
        // checkbox for skip server 
        JdCheckBox skipServerCheckBox = new JdCheckBox("Skip Server:", application.isSkipServer());
        skipServerCheckBox.onChange(t ->{
        	
        	application.setSkipServer(t);
//			serverFields.forEach(field -> field.setEditable(!t));
        });
        add(skipServerCheckBox);
        // checkbox for skip client
        JdCheckBox skipClientCheckBox = new JdCheckBox("Skip Client:", application.isSkipClient());
        skipClientCheckBox.onChange(t -> {
        	application.setSkipClient(t);
//        	clientFields.forEach(field -> field.setEditable(!t));
        });
        add(skipClientCheckBox);
        // server fields
        
        JdTextField packageNameTextField = new JdTextField("Package Name:", application.getPackageName());
        packageNameTextField.onChange(t -> application.setPackageName(t));
        add(packageNameTextField);
        serverFields.add(packageNameTextField);
        
        JdTextField tankPrefixTextField = new JdTextField("System Prefix:", application.getTankPrefix());
        tankPrefixTextField.onChange(t -> application.setTankPrefix(t));
        add(tankPrefixTextField);
		serverFields.add(tankPrefixTextField);
        
        JdTextField entitySuffixTextField = new JdTextField("Entity Suffix:", application.getEntitySuffix());
        entitySuffixTextField.onChange(t -> application.setEntitySuffix(t));
        add(entitySuffixTextField);
        serverFields.add(entitySuffixTextField);
        
        JdTextField dtoSuffixTextField = new JdTextField("DTO Suffix:", application.getDtoSuffix());
        dtoSuffixTextField.onChange(value -> application.setDtoSuffix(value));
        add(dtoSuffixTextField);
		serverFields.add(dtoSuffixTextField);
        
        JdComboBox<BuildTool> buildToolComboBox = new JdComboBox<>("Build Tool:", application.getBuildTool(), BuildTool.values());
        buildToolComboBox.onChange(value->application.setBuildTool(value));
        buildToolComboBox.setEditable(false);
        add(buildToolComboBox);
        serverFields.add(buildToolComboBox);
        
        JdComboBox<CacheProvider> cacheProviderComboBox = new JdComboBox<>("Cache Provider:", application.getCacheProvider(), CacheProvider.values());
        cacheProviderComboBox.onChange(value->application.setCacheProvider(value));
        cacheProviderComboBox.setEditable(false);
        add(cacheProviderComboBox);
		serverFields.add(cacheProviderComboBox);
        
        JdCheckBox hibernateCacheEnabledCheckBox = new JdCheckBox("Hibernate Cache:", application.isEnableHibernateCache());
        hibernateCacheEnabledCheckBox.onChange(t -> application.setEnableHibernateCache(t));
        add(hibernateCacheEnabledCheckBox);
        serverFields.add(hibernateCacheEnabledCheckBox);
        
        JdComboBox<DatabaseType> databaseTypeComboBox = new JdComboBox<>("Database Type:", application.getDatabaseType(), DatabaseType.values());
        databaseTypeComboBox.setEditable(false);
        databaseTypeComboBox.onChange(t -> application.setDatabaseType(t));
        add(databaseTypeComboBox);
		serverFields.add(databaseTypeComboBox);
        
        JdComboBox<DevDatabaseType> devDatabaseTypeComboBox = new JdComboBox<>("Dev Database Type:", application.getDevDatabaseType(), DevDatabaseType.values());
        devDatabaseTypeComboBox.setEditable(false);
        devDatabaseTypeComboBox.onChange(t -> application.setDevDatabaseType(t));
        add(devDatabaseTypeComboBox);
		serverFields.add(devDatabaseTypeComboBox);
        
        JdComboBox<ProdDatabaseType> prodDatabaseTypeComboBox = new JdComboBox<>("Prod Database Type:", application.getProdDatabaseType(), ProdDatabaseType.values());
        prodDatabaseTypeComboBox.onChange(t -> application.setProdDatabaseType(t));
        add(prodDatabaseTypeComboBox);
		serverFields.add(prodDatabaseTypeComboBox);
        
        JdCheckBox swaggerCodegenEnabledCheckBox = new JdCheckBox("Swagger Codegen:", application.isEnableSwaggerCodegen());
        swaggerCodegenEnabledCheckBox.onChange(t -> application.setEnableSwaggerCodegen(t));
        add(swaggerCodegenEnabledCheckBox);
		serverFields.add(swaggerCodegenEnabledCheckBox);
        
        JdCheckBox reactiveEnabledCheckBox= new JdCheckBox("Reactive:", application.isReactive());
        reactiveEnabledCheckBox.onChange(t -> application.setReactive(t));
        add(reactiveEnabledCheckBox);
		serverFields.add(reactiveEnabledCheckBox);
		
		JdCheckBox s3EnabledCheckBox = new JdCheckBox("S3:", application.isEnableS3());
		s3EnabledCheckBox.onChange(t -> application.setEnableS3(t));
		add(s3EnabledCheckBox);
		serverFields.add(s3EnabledCheckBox);
		
		JdCheckBox faceRecognitionEnabledCheckBox= new JdCheckBox("Face Recognition:", application.isEnableFaceRecognition());
		faceRecognitionEnabledCheckBox.onChange(t -> application.setEnableFaceRecognition(t));
		add(faceRecognitionEnabledCheckBox);
		serverFields.add(faceRecognitionEnabledCheckBox);
        
        JdComboBox<SearchEngine> searchEngineComboBox = new JdComboBox<>("Search Engine:", application.getSearchEngine(), SearchEngine.values());
        searchEngineComboBox.onChange(t -> application.setSearchEngine(t));
        add(searchEngineComboBox);
		serverFields.add(searchEngineComboBox);
        
       
        
        // comboBox for service discovery type
        
        JdComboBox<ServiceDiscoveryType> serviceDiscoveryTypeComboBox = new JdComboBox<>("Service Discovery Type:", application.getServiceDiscoveryType(),ServiceDiscoveryType.values());
        serviceDiscoveryTypeComboBox.onChange(t -> application.setServiceDiscoveryType(t));
        add(serviceDiscoveryTypeComboBox);
		serverFields.add(serviceDiscoveryTypeComboBox);
        // checkbox for skip user management 
        JdCheckBox skipUserManagementCheckBox = new JdCheckBox("Skip User Management:", application.isSkipUserManagement());
        skipUserManagementCheckBox.onChange(t -> application.setSkipUserManagement(t));
        add(skipUserManagementCheckBox);
        serverFields.add(skipUserManagementCheckBox);
        
        // combobox for websocket
        JdComboBox<Websocket> webSocketComboBox = new JdComboBox<>("Websocket:", application.getWebsocket(), Websocket.values());
        webSocketComboBox.onChange(t -> application.setWebsocket(t));
        add(webSocketComboBox);
		serverFields.add(webSocketComboBox);
        
      
        
        // client fields
        
        JdComboBox<ClientFramework> clientFrameworkComboBox = new JdComboBox<>("Client Framework:", application.getClientFramework(), ClientFramework.values());
        clientFrameworkComboBox.onChange(value->application.setClientFramework(value));
        add(clientFrameworkComboBox);
        clientFields.add(clientFrameworkComboBox);
        
        JdComboBox<String> clientPackageManagerComboBox = new JdComboBox<>("Client Package Manager:", "npm",new String[] {"npm"});
        clientPackageManagerComboBox.onChange(value->application.setClientPackageManager(value));
        add(clientPackageManagerComboBox);
        clientFields.add(clientPackageManagerComboBox);
        
        JdTextField clientThemeTextField= new JdTextField("Client Theme:", application.getClientTheme());
        clientThemeTextField.onChange(value->application.setClientTheme(value));
        add(clientThemeTextField);
        clientFields.add(clientThemeTextField);
        
        JdTextField clientThemeVariantTextField= new JdTextField("Client Theme Variant:", application.getClientThemeVariant());
        clientThemeVariantTextField.onChange(value->application.setClientThemeVariant(value));
        add(clientThemeVariantTextField);
        clientFields.add(clientThemeVariantTextField);
        
        
        JdCheckBox translationEnabledCheckBox = new JdCheckBox("Translation:", application.isEnableTranslation());
        translationEnabledCheckBox.onChange(t -> application.setEnableTranslation(t));
        add(translationEnabledCheckBox);
		clientFields.add(translationEnabledCheckBox);

        
        JdComboBox<String> languageComboBox = new JdComboBox<>("Language:", application.getNativeLanguage(), new String[] {"zh","en"});
        languageComboBox.onChange(t -> application.setNativeLanguage(t));
        add(languageComboBox);
        clientFields.add(languageComboBox);
        
        
        
        for(Component comp : this.getComponents()) {
        	if(comp instanceof JdLabeledInput) {
        		JdLabeledInput labeledInput = (JdLabeledInput)comp;
        		labeledInput.setInputComponentSize(150, 0);
        		labeledInput.setLabelSize(150, 0);
				labeledInput.onChange(obj->this.saved=false);
        	}
        }
        
        // list for testFrameworks
        
        // list for entities
        

       
    }

    
}
